package com.pan.kang.util;

import org.apache.commons.lang3.reflect.FieldUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static com.sun.el.util.ReflectionUtil.getPropertyDescriptor;

public class ClassUtil {

    public static void setAttribute(Object obj, String attrName, Object value) {
        Method md = null;
        PropertyDescriptor pd = getPropertyDescriptor(obj, attrName);
        if (pd != null) {
            md = pd.getWriteMethod();
        }

        if (md != null) {
            try {
                md.invoke(obj, value);
            } catch (Exception var8) {
                throw new RuntimeException("设置对象属性值失败");
            }
        } else {
            Field field = getClassFieldIncludeSuperClass(obj.getClass(), attrName);
            if (field != null) {
                try {
                    FieldUtils.writeField(field, obj, value, true);
                } catch (Exception var7) {
                    throw new RuntimeException("设置对象属性值失败");
                }
            }
        }

    }

    public static Field getClassFieldIncludeSuperClass(Class cls, String name) {
        Field fld = getClassField(cls, name);
        if (fld == null) {
            for(Class parentCls = cls.getSuperclass(); parentCls != null; parentCls = parentCls.getSuperclass()) {
                fld = getClassField(parentCls, name);
                if (fld != null) {
                    break;
                }
            }
        }

        return fld;
    }

    public static Field getClassField(Class cls, String name) {
        return (Field)getClassFieldMap(cls).get(name);
    }

    public static Map getClassFieldMap(Class cls) {
        Map map = new ConcurrentHashMap();
        Field[] fields = cls.getDeclaredFields();
        Field fld = null;
        for(int i = 0; i < fields.length; ++i) {
            fld = fields[i];
            map.put(fld.getName(), fld);
        }

        return map;
    }
}
